package com.zhz.controller;

import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.zhz.config.AlipayConfig;
import com.zhz.pojo.Order;
import com.zhz.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Controller
@RequestMapping("/Alipay")
@Slf4j
public class AliPayController {

    @Resource
    private OrderService service;

    /**
     * 支付
     *
     * @param orderNo
     * @param model
     * @return
     */
    @RequestMapping("/pay/{orderNo}")
    @ResponseBody
    public String pay(@PathVariable("orderNo") String orderNo, Model model, HttpServletResponse response) {
        log.info("支付宝支付请求");
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);

        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(AlipayConfig.return_url);
        alipayRequest.setNotifyUrl(AlipayConfig.notify_url);

        Order order = service.findOrderNO(orderNo);
        try {
            alipayRequest.setBizContent("{\"out_trade_no\":\"" + order.getOrderNo() + "\","
                    + "\"total_amount\":\"" + order.getAmount() + "\","
                    + "\"subject\":\"" + order.getSubject() + "\","
                    + "\"body\":\"" + order.getBody() + "\","
                    + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
            log.info("BizContent={}",alipayRequest.getBizContent());
            String result = alipayClient.pageExecute(alipayRequest).getBody();
            log.info("result={}",result);
            AlipayConfig.logResult(result);// 记录支付日志
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            model.addAttribute("error", e.getMessage());
            return "error";
        }
    }

    @RequestMapping("/return_url")
    public String returnUrl(HttpServletRequest request, Model model) {
        Map<String, String> params = new HashMap<>();
        Map<String, String[]> requestParam = request.getParameterMap();
        try {
            for (Iterator<String> iter = requestParam.keySet().iterator(); iter.hasNext(); ) {
                String name = iter.next();
                String[] values = requestParam.get(name);
                String valueStr = "";
                for (int i = 0; i < values.length; i++) {
                    valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
                }
                valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
                params.put(name, valueStr);
            }
            boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type);
            if (signVerified) {
                //商户订单号
                String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");

                //支付宝交易号
                String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");

                //付款金额
                String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "UTF-8");
                model.addAttribute("orderNo", out_trade_no);
            } else {
                model.addAttribute("error", "验签失败");
                return "error";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "success";
    }

    @RequestMapping("/notify_url")
    public String notifyUrl(HttpServletRequest request, Model model) {
        Map<String, String> params = new HashMap<>();
        Map<String, String[]> requestParam = request.getParameterMap();
        try {
            for (Iterator<String> iter = requestParam.keySet().iterator(); iter.hasNext(); ) {
                String name = iter.next();
                String[] values = requestParam.get(name);
                String valueStr = "";
                for (int i = 0; i < values.length; i++) {
                    valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
                }
                valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
                params.put(name, valueStr);
            }
            boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type);
            if (signVerified) {
                //商户订单号
                String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");

                //支付宝交易号
                String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");

                String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");

                if (trade_status.equals("TRADE_FINISHED")) {
                    //判断该笔订单是否在商户网站中已经做过处理
                    //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                    //如果有做过处理，不执行商户的业务程序

                    //注意：
                    //退款日期超过可退款期限后（如三个月可退款），支付宝系统发送该交易状态通知
                } else if (trade_status.equals("TRADE_SUCCESS")) {
                    //判断该笔订单是否在商户网站中已经做过处理
                    //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                    //如果有做过处理，不执行商户的业务程序
                    Order order = service.findOrderNO(out_trade_no);
                    if (order != null && order.getStatus() == 0) {
                        order.setPayType(1);
                        order.setStatus(1);
                        order.setTrade_no(trade_no);
                        service.save(order);
                    }
                    //注意：
                    //付款完成后，支付宝系统发送该交易状态通知
                }
            } else {
                model.addAttribute("error", "fail");
                return "error";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "success";
    }
}
